package com.hongkuncheng.cms.controller.admin;

import com.hongkuncheng.cms.controller.BaseController;
import com.hongkuncheng.cms.helper.*;
import com.hongkuncheng.cms.model.*;
import org.hibernate.Criteria;
import org.hibernate.LockMode;
import org.hibernate.criterion.*;
import org.hibernate.sql.JoinType;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 文档审核管理
 *
 * @author 洪坤成
 */
@Controller
@Transactional
@RequestMapping("admin/articlecheck")
public class AarticlecheckController extends BaseController {

    // 待我审核的文档列表
    @RequestMapping
    public String index() {
        Admin admin = (Admin) request.getSession().getAttribute("admin");
        admin = factorySession.get(Admin.class, admin.getId());
        Criteria criteriaArticle = factorySession.createCriteria(Article.class, "this_")
                .createAlias("checknode", "article_checknode", JoinType.LEFT_OUTER_JOIN)
                .createAlias("article_checknode.checknodeReAdmins", "cnra", JoinType.LEFT_OUTER_JOIN)
                .createAlias("cnra.checknode", "cnra_checknode")
                .add(Restrictions.eq("cnra_checknode.checknodeType.id", 2))
                .add(Restrictions.eq("cnra.admin.id", admin.getId()));
        StringBuilder callbackparams = new StringBuilder();
        String title = request.getParameter("title") == null ? "" : request.getParameter("title");
        if (!title.isEmpty()) {
            criteriaArticle.add(Restrictions.like("title", title, MatchMode.ANYWHERE));
            callbackparams.append("&title=" + title);
        }
        request.setAttribute("title", title);
        List<Article> articleTemps = criteriaArticle.list(); // 临时数据集合
        List<Integer> articleIds = new ArrayList<Integer>();
        for (Article article : articleTemps) {
            if (article.getChecknode().isGroupbydepart())
                if (article.getAdmin().getDepartment().getId() != admin.getDepartment().getId()) continue;
            if (!article.getChecknode().isSingleaudit()) {
                // 会审
                // 获取审核记录集里和当前节点不同的最大ID值
                Object uniqueResult = factorySession.createCriteria(Checkrecord.class)
                        .add(Restrictions.eq("article.id", article.getId()))
                        .add(Restrictions.or(Restrictions.and(Restrictions.isNotNull("checknode"),
                                Restrictions.ne("checknode.id", article.getChecknode().getId())),
                                Restrictions.and(Restrictions.isNull("checknode"),
                                        Restrictions.eq("checkrecordResult.id", 3))))
                        .setProjection(Projections.max("id")).uniqueResult();
                int neqmaxId = uniqueResult == null ? 0 : Integer.parseInt(uniqueResult.toString());
                // 获取当前文档当前审核节点已经参与审核的人员数（限当前用户），用于验证已会审人员是否包含当前用户
                uniqueResult = factorySession.createCriteria(Checkrecord.class)
                        .add(Restrictions.eq("article.id", article.getId()))
                        .add(Restrictions.eq("checknode.id", article.getChecknode().getId()))
                        .add(Restrictions.gt("id", neqmaxId))
                        .add(Restrictions.eq("admin.id", admin.getId()))
                        .setProjection(Projections.count("id"))
                        .setProjection(Projections.countDistinct("id"))
                        .uniqueResult();
                if (uniqueResult == null || Integer.parseInt(uniqueResult.toString()) == 0)
                    articleIds.add(article.getId());
            } else {
                articleIds.add(article.getId());
            }
        }
        if (callbackparams.length() > 0) callbackparams.deleteCharAt(0);
        request.setAttribute("callbackparams", callbackparams);
        int pageIndex = request.getParameter("pageindex") == null || request.getParameter("callbackparams") != null &&
                !callbackparams.toString().equals(request.getParameter("callbackparams")) ? 1 :
                Integer.parseInt(request.getParameter("pageindex"));
        int datasize = getDataSize();
        List<Article> articles = new ArrayList<Article>();
        if (articleIds.size() > 0)
            articles = factorySession.createCriteria(Article.class).add(Restrictions.in("id", articleIds))
                    .addOrder(Order.desc("id")).setFirstResult((pageIndex - 1) * datasize).setMaxResults(datasize)
                    .list();
        request.setAttribute("articles", articles);
        request.setAttribute("pageindex", pageIndex);
        int recordcount = articles.size() == 0 ? 0 : Integer.parseInt(criteriaArticle
                .setProjection(Projections.countDistinct("id")).setFirstResult(0)
                .uniqueResult().toString());
        request.setAttribute("recordcount", recordcount);
        int pagecount = DataHelper.calcPageCount(recordcount, datasize);
        request.setAttribute("pagecount", pagecount);
        return view();
    }

    // 文档审核
    @RequestMapping("check")
    @ResponseBody
    public void check() throws Exception {
        int articleId = Integer.parseInt(request.getParameter("articleid"));
        Article article = factorySession.get(Article.class, articleId);
        response.sendRedirect((article.getChecknode().isCanedit() ? "edit" : "detail") + "?articleid=" +
                articleId + "&callbackparams=" + request.getParameter("callbackparams"));
    }

    // 文档审核（可编辑）
    @RequestMapping("edit")
    public String edit() {
        int articleId = Integer.parseInt(request.getParameter("articleid"));
        Article article = factorySession.get(Article.class, articleId);
        List<Integer> columnsIds = new ArrayList<Integer>();
        for (ArticleReColumns arc : article.getArticleReColumnses()) columnsIds.add(arc.getColumns().getId());
        request.setAttribute("article", article);
        request.setAttribute("columnsIds", columnsIds);
        // 栏目集合
        List<Columns> columnses = new ArrayList<Columns>();
        List<Columns> columnsForZhuanties = new ArrayList<Columns>();
        List<Zhuanti> zhuantis = new ArrayList<Zhuanti>();
        List<Integer> zhuantiIds = new ArrayList<Integer>();
        List<Columns> columns1es = factorySession.createCriteria(Columns.class)
                .add(Restrictions.eq("parentId", 0)).addOrder(Order.asc("sort")).list();
        for (Columns columns1 : columns1es) {
            List<Columns> columns2Temp = factorySession.createCriteria(Columns.class)
                    .add(Restrictions.eq("columnsType.id", 1))
                    .add(Restrictions.eq("parentId", columns1.getId()))
                    .addOrder(Order.asc("sort")).list();
            if (columns1.getColumnsType().getId() == 1 || columns2Temp.size() > 0)
                columnses.add(columns1);
            if (columns2Temp.size() > 0)
                for (Columns columns2 : columns2Temp) columnses.add(columns2);
            if (columns1.getColumnsType().getId() == 6) {
                if (!zhuantiIds.contains(columns1.getZhuanti().getId())) {
                    zhuantis.add(columns1.getZhuanti());
                    zhuantiIds.add(columns1.getZhuanti().getId());
                }
                columnsForZhuanties.add(columns1);
            }
        }
        request.setAttribute("columnses", columnses);
        request.setAttribute("zhuantis", zhuantis);
        request.setAttribute("columnsForZhuanties", columnsForZhuanties);
        Systemsetup systemSetup = factorySession.get(Systemsetup.class, 1);
        request.setAttribute("checkOpinions", systemSetup.getCheckopinion() == null ? new String[0] :
                systemSetup.getCheckopinion().split(","));
        request.setAttribute("callbackparams", request.getParameter("callbackparams"));
        return view();
    }

    // 文档审核（不可编辑）
    @RequestMapping("detail")
    public String detail() {
        int articleId = Integer.parseInt(request.getParameter("articleid"));
        Article article = factorySession.get(Article.class, articleId);
        List<Integer> columnsIds = new ArrayList<Integer>();
        for (ArticleReColumns arc : article.getArticleReColumnses()) columnsIds.add(arc.getColumns().getId());
        request.setAttribute("article", article);
        request.setAttribute("columnsIds", columnsIds);
        // 栏目集合
        List<Columns> columnses = new ArrayList<Columns>();
        List<Columns> columnsForZhuanties = new ArrayList<Columns>();
        List<Zhuanti> zhuantis = new ArrayList<Zhuanti>();
        List<Integer> zhuantiIds = new ArrayList<Integer>();
        List<Columns> columns1es = factorySession.createCriteria(Columns.class)
                .add(Restrictions.eq("parentId", 0)).addOrder(Order.asc("sort")).list();
        for (Columns columns1 : columns1es) {
            List<Columns> columns2Temp = factorySession.createCriteria(Columns.class)
                    .add(Restrictions.eq("columnsType.id", 1))
                    .add(Restrictions.eq("parentId", columns1.getId()))
                    .addOrder(Order.asc("sort")).list();
            if (columns1.getColumnsType().getId() == 1 || columns2Temp.size() > 0)
                columnses.add(columns1);
            if (columns2Temp.size() > 0)
                for (Columns columns2 : columns2Temp) columnses.add(columns2);
            if (columns1.getColumnsType().getId() == 6) {
                if (!zhuantiIds.contains(columns1.getZhuanti().getId())) {
                    zhuantis.add(columns1.getZhuanti());
                    zhuantiIds.add(columns1.getZhuanti().getId());
                }
                columnsForZhuanties.add(columns1);
            }
        }
        request.setAttribute("columnses", columnses);
        request.setAttribute("zhuantis", zhuantis);
        request.setAttribute("columnsForZhuanties", columnsForZhuanties);
        Systemsetup systemSetup = factorySession.get(Systemsetup.class, 1);
        request.setAttribute("checkOpinions", systemSetup.getCheckopinion() == null ? new String[0] : systemSetup.getCheckopinion().split(","));
        request.setAttribute("callbackparams", request.getParameter("callbackparams"));
        return view();
    }

    // 审核编辑处理
    @RequestMapping("checkdo")
    @ResponseBody
    public void checkdo() {
        checkAdminPermission("office_article_check");
        Admin admin = (Admin) request.getSession().getAttribute("admin");
        admin = factorySession.get(Admin.class, admin.getId());
        int articleId = Integer.parseInt(request.getParameter("articleid"));
        Article article = factorySession.load(Article.class, articleId, LockMode.PESSIMISTIC_WRITE);
        if (article.getChecknode() == null) {
            PageHelper.alertAndRedirect("该文档已被其它管理人员处理,并已" + article.getArticleState().getName(), "./");
            return;
        }
        // 判断当前审核节点是否包含自己
        boolean havecheckflow = false;
        for (ChecknodeReAdmin cra : article.getChecknode().getChecknodeReAdmins()) {
            if (cra.getAdmin().getId() == admin.getId()) {
                havecheckflow = true;
                break;
            }
        }
        if (!havecheckflow) {
            PageHelper.alertAndRedirect("该文档已被其它管理人员处理,并下一审核节点没有您的审核",
                    "./?" + request.getParameter("callbackparams"));
            return;
        }
        int canedit = Integer.parseInt(request.getParameter("canedit"));
        if (canedit == 1) {
            // 有编辑权限
            article.setTitle(request.getParameter("title"));
            article.setBold(request.getParameter("bold") != null);
            article.setRed(request.getParameter("red") != null);
            article.setDigest(request.getParameter("digest"));
            article.setExturl(request.getParameter("exturl"));
            article.setContents(request.getParameter("contents"));
            article.setContenttext(StringHelper.escapeHtml(request.getParameter("contents")));
            article.setImage(request.getParameter("image"));
            article.setSource(request.getParameter("source"));
            article.setAuthor(request.getParameter("author"));
            article.setPublishtime(DateHelper.convertToDatetime(request.getParameter("publishtime")));
            article.setClicknum(Integer.parseInt(request.getParameter("clicknum")));
            article.setSort(Integer.parseInt(request.getParameter("sort")));
            if (request.getParameter("protection") != null) {
                article.setProtection(true);
                article.setProtectionpassword(request.getParameter("protectionpassword"));
            } else {
                article.setProtection(false);
                article.setProtectionpassword(null);
            }
            List<Integer> columnsIds = DataHelper.convertToIntegerList(request.getParameterValues("columnsids"));
            if (article.getArticleReColumnses().size() > 0) {
                // 删除原来的映射关系
                List<Object> arcs = new ArrayList<>();
                for (ArticleReColumns arc : article.getArticleReColumnses()) {
                    if (!columnsIds.contains(arc.getColumns().getId())) arcs.add(arc);
                    else columnsIds.remove(Integer.valueOf(arc.getColumns().getId()));
                }
                factorySession.delete(arcs);
            }
            if (columnsIds.size() > 0) {
                // 创建新的映射关系
                List<Columns> columnses = factorySession.createCriteria(Columns.class)
                        .add(Restrictions.in("id", columnsIds)).list();
                for (Columns columns : columnses) {
                    ArticleReColumns arc = new ArticleReColumns();
                    arc.setArticle(article);
                    arc.setColumns(columns);
                    factorySession.save(arc);
                }
            }
        }
        // 当前文档参与的审核节点
        List<Checknode> checknodes = factorySession.createCriteria(Checknode.class)
                .add(Restrictions.eq("checkflow.id", article.getChecknode().getCheckflow().getId()))
                .add(Restrictions.eq("checknodeType.id", 2)).addOrder(Order.asc("sort")).list();
        // 审核记录
        Checkrecord checkrecord = new Checkrecord();
        checkrecord.setAdmin(admin);
        checkrecord.setArticle(article);
        checkrecord.setChecknode(article.getChecknode());
        // 当前审核节点在节点集合中的索引
        int nodeIndex = 0;
        for (int i = 0; i < checknodes.size(); i++) {
            if (checknodes.get(i).getId() == article.getChecknode().getId()) {
                nodeIndex = i;
                break;
            }
        }
        String msg = null;
        Notice notice = new Notice();
        int checktype = Integer.parseInt(request.getParameter("checktype"));
        if (checktype == 1) {
            // 审核通过
            // 获取审核记录集里和当前节点不同的最大ID值
            Object uniqueResult = factorySession.createCriteria(Checkrecord.class)
                    .add(Restrictions.eq("article.id", article.getId()))
                    .add(Restrictions.or(Restrictions.and(Restrictions.isNotNull("checknode"),
                            Restrictions.ne("checknode.id", article.getChecknode().getId())),
                            Restrictions.and(Restrictions.isNull("checknode"),
                                    Restrictions.eq("checkrecordResult.id", 3))))
                    .setProjection(Projections.max("id")).uniqueResult();
            int neqmaxId = uniqueResult == null ? 0 : Integer.parseInt(uniqueResult.toString());
            // 获取当前文档当前审核节点已经参与审核的人员数
            uniqueResult = factorySession.createCriteria(Checkrecord.class)
                    .add(Restrictions.gt("id", neqmaxId))
                    .add(Restrictions.eq("article.id", articleId))
                    .add(Restrictions.eq("checknode.id", article.getChecknode().getId()))
                    .setProjection(Projections.count("id"))
                    .setProjection(Projections.countDistinct("id")).uniqueResult();
            // 会审人数
            int huicheckcount = article.getChecknode().isSingleaudit() ? 0 : (uniqueResult == null ? 0 :
                    Integer.parseInt(uniqueResult.toString()));
            // 等待审核人员人数
            int waitecheckusercount = 0;
            if (article.getChecknode().isGroupbydepart()) {
                for (ChecknodeReAdmin cra : article.getChecknode().getChecknodeReAdmins())
                    if (article.getAdmin().getDepartment().getId() == cra.getAdmin().getDepartment().getId())
                        waitecheckusercount++;
            } else {
                waitecheckusercount = article.getChecknode().getChecknodeReAdmins().size();
            }
            if (article.getChecknode().isSingleaudit() || !article.getChecknode().isSingleaudit() &&
                    waitecheckusercount - huicheckcount == 1) {
                // 单审或者当前参与会审的人员只剩一个
                if (nodeIndex == checknodes.size() - 1) {
                    // 如果是最后一个审核节点，就直接发布
                    ArticleState articleState = factorySession.load(ArticleState.class, 4);
                    article.setArticleState(articleState);
                    article.setChecknode(null);
                    msg = "已发布";
                    notice.setAdmin(article.getAdmin());
                    notice.setMessage("您提交审核的文档《" + article.getTitle().trim() + "》已审核通过");
                    notice.setRedirecturl("../article/?stateid=4");
                    factorySession.save(notice);
                } else {
                    // 不是最后一个节点，将文档节点改为当前节点的下一个节点
                    article.setChecknode(checknodes.get(nodeIndex + 1));
                    msg = "已进入下一个流程节点";
                }
            } else {
                // 会审，且当前操作人员不是当前文件当前节点最后一个参与人员
                msg = "正等待其它人员会审";
            }
            CheckrecordResult checkrecordResult = factorySession.load(CheckrecordResult.class, 1);
            checkrecord.setCheckrecordResult(checkrecordResult);
        } else {
            if (nodeIndex == 0) {
                // 如果是首个审核节点，就直接回到文档驳回状态
                ArticleState articleState = factorySession.load(ArticleState.class, 2);
                article.setArticleState(articleState);
                article.setChecknode(null);
                msg = "已驳回";
                notice.setAdmin(article.getAdmin());
                notice.setMessage("您提交审核的文档《" + article.getTitle().trim() + "》已审核驳回");
                notice.setRedirecturl("../article/?stateid=2");
                factorySession.save(notice);
            } else {
                // 不是首个节点，将文章节点改为当前的上一个节点
                article.setChecknode(checknodes.get(nodeIndex - 1));
                msg = "已驳回到上一个流程节点";
            }
            CheckrecordResult checkrecordResult = factorySession.load(CheckrecordResult.class, 2);
            checkrecord.setCheckrecordResult(checkrecordResult);
        }
        checkrecord.setOpinion(request.getParameter("opinion"));
        checkrecord.setSubmittime(new Date());
        factorySession.save(checkrecord);
        recordLog("审核文档《" + article.getTitle().trim() + "》");
        if (article.getArticleState().getId() == 4 && AdminHelper.checkAdminPermission(admin, "office_create_")) {
            PageHelper.confirmAndRedirect("审核成功，该文档" + msg + "，是否生成相关静态页面？",
                    "../createpage/articlerelevancefilepaths?articleids=" + article.getId(),
                    "./?" + request.getParameter("callbackparams"));
        } else {
            PageHelper.alertAndRedirect("审核成功，该文档" + msg, "./?" + request.getParameter("callbackparams"));
        }
    }

    // 经我审核的文档列表
    @RequestMapping("checked")
    public String checked() {
        checkAdminPermission("office_article_checked");
        Admin admin = (Admin) request.getSession().getAttribute("admin");
        Criteria criteriaArticle = factorySession.createCriteria(Article.class)
                .createAlias("checkrecords", "checkrecords", JoinType.LEFT_OUTER_JOIN)
                .add(Restrictions.isNotNull("checkrecords.checkrecordResult"))
                .add(Restrictions.eq("checkrecords.admin.id", admin.getId()));
        StringBuilder callbackparams = new StringBuilder();
        String title = request.getParameter("title") == null ? "" : request.getParameter("title");
        if (!title.isEmpty()) {
            criteriaArticle.add(Restrictions.like("title", title, MatchMode.ANYWHERE));
            callbackparams.append("&title=" + title);
        }
        request.setAttribute("title", title);
        if (callbackparams.length() > 0) callbackparams.deleteCharAt(0);
        request.setAttribute("callbackparams", callbackparams);
        int pageIndex = request.getParameter("pageindex") == null || request.getParameter("callbackparams") != null &&
                !callbackparams.toString().equals(request.getParameter("callbackparams")) ? 1 :
                Integer.parseInt(request.getParameter("pageindex"));
        int datasize = getDataSize();
        List<Article> articles = criteriaArticle.addOrder(Order.desc("id")).setFirstResult((pageIndex - 1) * datasize)
                .setMaxResults(datasize).list();
        request.setAttribute("articles", articles);
        request.setAttribute("pageindex", pageIndex);
        int recordcount = articles.size() == 0 ? 0 : Integer.parseInt(criteriaArticle
                .setProjection(Projections.countDistinct("id")).setFirstResult(0)
                .uniqueResult().toString());
        request.setAttribute("recordcount", recordcount);
        int pagecount = DataHelper.calcPageCount(recordcount, datasize);
        request.setAttribute("pagecount", pagecount);
        return view();
    }

}
